import { getScale, getElement, getYHeight, getGainValue } from "./ecgPublic";
import { oQueue } from './queue'
import { isLoginEd, getSn } from '@/utils/publicMethods'

// 基本线条配置
let ecgParams = {
  speed: 25, // 走速：单位：mm/s , 每秒数据显示的长度 （25mm/s = 每秒钟数据显示成25mm 的长度）
  ppm: 4, // 一mm有多少个像素
  gain: 10, // 每1mV的电压值显示的高度 (10mm/mV = 每1mV电压显示成10mm的高度)
  duvp: 2.44, // 每1单位采样点代表的电压值(微伏:uV)
  nFs: 250, // 每秒采样点数
  dpr: getScale(true), // 设备像素比
  lineWidth: 1.5, // 线宽
  lineColor: '#000000', // 线条色
  gridScale: 1, //波形缩放比例
  baseLineValue: 0, // 数据基线值(marginTop)
  bottomBlank: 0, // 下留白(px)
  leadValueList: [],
  leadNameList: [],
  canvasWidth: 0,
  canvasHeight: 0,
  element: '.canvas-line',
  startYList: [],
  startX: 0, // 开始绘制的位置
  distribution: 'between', // 分布方式：'equal':等分，'custom':自定义
}

// 计算参数
let computedParams = {
  width: 0, //页面宽度
  screenLen: 0, //一屏显示的波形组数
  useData: [], // 需要消费的数据
  useCount: 6, // 每次需要消费的数组个数
  useIndex: 0, // 当前消费过的数组的个数
  queueData: [], // 队列数据
  leadCount: 0, // 导联个数
  blankData: [0], // 一组空白（横线）数据,（[0]*leadCount）
  second: 25, // 计时时间（毫秒）
  initSecond: 25, // 计时时间固定值
  lucencyWidth: 10, // 透光宽度
  moveLen: 0, // 移动的X轴的数组个数
  moveX: 0, // 移动的X轴的像素个数
  moveYList: [], // 最后一次绘制的已计算过的Y轴合集
  isStop: true, // 是否停止绘制
}

// 初始化部分参数,给队列用
export const initEcgPart = (params) => {
  ecgParams.ppm = params.ppm
  ecgParams.gain = params.gain
  ecgParams.duvp = params.duvp
  ecgParams.speed = params.speed
  computedParams.leadCount = params.leadCount || 0 // 空白导联个数
  computedParams.blankData = getBlankData(params.leadCount) // 一组空白导联数据
  if (ecgParams.nFs !== params.nFs || !oQueue.GetSize()) {  //每秒采样点数
    ecgParams.nFs = params.nFs
    computedParams.useCount = params.nFs === 125 ? 6 : params.nFs === 250 ? 7 : params.nFs === 500 ? 9 : 11
    computedParams.second = params.nFs === 125 ? 50 : params.nFs === 250 ? 25 : params.nFs === 500 ? 16 : 10
    computedParams.initSecond = computedParams.second
    computedParams.screenLen = getScreenLen(params.canvasWidth)
  }
}

// 初始化基本参数
export const initEcgParams = async (params) => {
  ecgParams.ppm = params.ppm
  ecgParams.gain = params.gain
  ecgParams.duvp = params.duvp
  ecgParams.nFs = params.nFs
  ecgParams.speed = params.speed
  ecgParams.lineWidth = params.lineWidth || 1.5
  ecgParams.lineColor = params.lineColor || '#000000'
  ecgParams.gridScale = params.gridScale || 1
  ecgParams.canvasWidth = params.canvasWidth || 0
  ecgParams.canvasHeight = params.canvasHeight || 0
  ecgParams.element = params.element || ''
  ecgParams.leadValueList = params.leadValueList || []
  ecgParams.leadNameList = params.leadNameList || []
  ecgParams.baseLineValue = params.baseLineValue ? params.baseLineValue - 0 : 0
  ecgParams.distribution = params.distribution || 'between'
  ecgParams.startX = params.startX || 0
  ecgParams.bottomBlank = params.bottomBlank || 0
  ecgParams.startYList = getYHeight(ecgParams.leadValueList.length, ecgParams.canvasHeight - ecgParams.bottomBlank, ecgParams.gridScale, ecgParams.distribution)
  computedParams.screenLen = getScreenLen(params.canvasWidth)
  // 获取canvas对象
  return await getContext_()
}

// 初始化计算参数
export const initComputedParams = (params, isClearCanvas) => {
  computedParams.useData = []
  computedParams.queueData = []
  computedParams.isStop = false
  computedParams.useIndex = 0
  computedParams.moveX = 0
  computedParams.moveLen = params.moveLen || 0
  computedParams.lucencyWidth = params.lucencyWidth || 10
  computedParams.moveYList = initListY(ecgParams.leadValueList, ecgParams.leadNameList)
  // 清除队列数据
  oQueue.MakeEmpty()
  // 清除页面波形
  !isClearCanvas && clearCanvas()
}

// canvas对象
let ctx = null
const getContext_ = async () => {
  let canvasElement = await getElement(ecgParams.element)
  const canvas = canvasElement?.node
  if (!canvas) return false
  ctx = canvas.getContext('2d')
  if (!ctx) { return false }
  canvas.width = ecgParams.canvasWidth * ecgParams.dpr
  canvas.height = ecgParams.canvasHeight * ecgParams.dpr
  ctx.scale(ecgParams.dpr, ecgParams.dpr)
  return true
}
// 一组空白导联数据
const getBlankData = (leadCount) => {
  let blankData = []
  for (let i = 0; i < leadCount; i++) {
    blankData[i] = 0
  }
  return blankData
}

// 被定时调用，压入数据
export const pushData = (data) => {
  data.forEach(item => {
    oQueue.EnQueue(item)
  });
  if (oQueue.GetSize()) {
    computedParams.isStop = false
    loop()
  }
}

let loopTimerId = null; // 用于存储定时器的ID

export const loop = () => {

  // 如果定时器已经在运行，则清除它
  if (!isLoginEd()) {
    console.log('未登录，停止绘制波形')
    oQueue.MakeEmpty()
    clearCanvas()
    return
  }

  // 解绑也要清除
  if (!getSn()) {
    console.log('没有设备ID，停止绘制波形')
    return
  }

  // 如果队列个数大于10s数据则，需要清空重新绘制
  // if (oQueue.GetSize() > ecgParams.nFs * 10 + ecgParams.nFs * 5) {
  //   oQueue.MakeEmpty()
  //   clearCanvas()
  //   return
  // }

  if (loopTimerId !== null) {
    clearTimeout(loopTimerId);
  }

  // 检查队列大小，如果为0，则停止定时器
  if (!oQueue.GetSize()) {
    computedParams.isStop = true;
  }

  // 定时器循环调用，如果为true，则不设置定时器
  if (!computedParams.isStop) {

    // 设置新定时器，并存储其ID
    loopTimerId = setTimeout(loop, computedParams.second);

    // 无论是否设置定时器，都执行draw函数
    draw();
  }

}

// 画图逻辑
const draw = async () => {
  /*
    队列 5 [[0,1,1,3,4,5,6],[1,3,4,5,6,67,7],[2,2,,4,5,6,7],[3,4,5,6,7,8,9]]
    规定个娄 10 个 [[0,1,1,3,4,5,6],[1,3,4,5,6,67,7],[2,2,,4,5,6,7],[3,4,5,6,7,8,9],[2,2,,4,5,6,7],[3,4,5,6,7,8,9]]
  */
  // debugger
  let useList = [];
  if (!oQueue.GetSize()) {
    return
  }

  // 当队列的数据小于规定的个数时
  if (oQueue.GetSize() < computedParams.useCount) {
    const len = oQueue.GetSize()
    for (let i = 0; i < len; i++) {
      useList.push(oQueue.DeQueue());
    }
  } else {
    // 移除队列中以设定为10个的list,放到useList中
    for (let J = 0; J < computedParams.useCount; J++) {
      useList.push(oQueue.DeQueue());
    }
  }
  // 当前的组数累加是否大于总组数
  let indexMoveLen = -1
  const useListLen = useList.length
  let countMore = computedParams.moveLen + useListLen
  // console.log('超出屏幕长度，重新计算', countMore, computedParams.screenLen, oQueue.GetSize())

  if (countMore > computedParams.screenLen) {
    indexMoveLen = useListLen - (countMore - computedParams.screenLen)
    computedParams.moveLen = 0
    computedParams.moveX = 0
    setSecond()
  }

  let contentStatus = false
  if (indexMoveLen > -1) {
    contentStatus = await clearLine(computedParams.moveX);
  } else {
    contentStatus = await clearLine(computedParams.moveX + 1);
  }
  if (!contentStatus) return

  // 2、开始画线（10个一画）
  ctx.beginPath();
  ctx.lineWidth = ecgParams.lineWidth;
  ctx.imageSmoothingEnabled = true; // 开启图像平滑
  // 绘制波形
  ecgParams.leadValueList.forEach((item, index) => {
    const startY = ecgParams.startYList[index] + ecgParams.baseLineValue;
    const gain_ = getGainValue(ecgParams.gain, ecgParams.leadNameList[item]);
    const dy = (ecgParams.duvp * ecgParams.ppm * gain_) / 1000 * ecgParams.gridScale;
    const dx = (ecgParams.speed * ecgParams.ppm) / ecgParams.nFs;
    // 2、画线
    useList.forEach((list, N) => {
      // 画高度
      const speedHeight = startY - dy * list[item];
      // 画宽度（截取数组从截取的第indexMoveLen个开始画）
      if (indexMoveLen > -1 && N >= indexMoveLen) {
        const newN = N - indexMoveLen
        const speedWidth = ecgParams.startX + dx * (newN + 1) * ecgParams.gridScale;
        if (newN === 0) {
          ctx.moveTo(0, speedHeight);
        }
        ctx.lineTo(speedWidth, speedHeight);
      } else {
        // 衔接画线
        const speedWidth = ecgParams.startX + dx * (N + 1) * ecgParams.gridScale;
        if (N === 0) {
          ctx.moveTo(computedParams.moveX, computedParams.moveYList[item]);
        }
        ctx.lineTo(computedParams.moveX + speedWidth, speedHeight);
      }
      if (N === useList.length - 1) {
        computedParams.moveYList[item] = speedHeight;
      }
    })

  })
  ctx.stroke();

  // 画完后把真实的移动距离计算出来
  if (indexMoveLen > -1) {
    computedParams.moveLen = useListLen - indexMoveLen
    computedParams.moveX = useListMove(useListLen - indexMoveLen)
  } else {
    computedParams.moveLen = computedParams.moveLen + useListLen;
    computedParams.moveX = computedParams.moveX + useListMove(useListLen);
  }

}

// 设置时间间隔
const useSecond = 3
// 如何队列中的数据大于小于一定的数量时，则对波形适当加减速
const setSecond = () => {
  const queueSize = oQueue.GetSize()
  const result = Math.floor(computedParams.initSecond / 2);
  const nfsMultiple = ecgParams.nFs * 10
  if (queueSize > nfsMultiple) {
    if (computedParams.second <= computedParams.initSecond - result) {
      computedParams.second = computedParams.initSecond - result
      return
    }
    if (computedParams.second > computedParams.initSecond) {
      computedParams.second = computedParams.initSecond - useSecond
      return
    }
    computedParams.second -= useSecond
  } else {
    if (computedParams.second >= computedParams.initSecond + result) {
      computedParams.second = computedParams.initSecond + result
      return
    }
    if (computedParams.second < computedParams.initSecond) {
      computedParams.second = computedParams.initSecond + useSecond
      return
    }
    computedParams.second += useSecond
  }
  console.log(queueSize, nfsMultiple, computedParams.second, computedParams.initSecond)
}

// 走动清空的透明动作线（可以设置透明线宽度）
const clearLine = async (moveX) => {
  const onceX = useListMove(computedParams.useCount)
  if (!ctx) {
    const isCtx = await getContext_()
    if (!isCtx) return false
  }
  ctx.clearRect(moveX, 0, onceX + ecgParams.ppm, ecgParams.canvasHeight);
  return true
};

// 清除画布
export const clearCanvas = async () => {
  if (!ctx) {
    const isCtx = await getContext_()
    if (!isCtx) return false
  }
  ctx.clearRect(
    0 - computedParams.lucencyWidth,
    0 - computedParams.lucencyWidth,
    ecgParams.canvasWidth + computedParams.lucencyWidth,
    ecgParams.canvasHeight + computedParams.lucencyWidth,
  )
  computedParams.moveX = 0
  computedParams.moveLen = 0
}

// 清除队列+定时器
export const clearQueueLoopTimer = () => {
  oQueue.MakeEmpty()
  clearTimeout(loopTimerId);
}

// 初始化Y的高度
const initListY = (leadValueList, leadNameList) => {
  let list = []
  leadValueList.forEach((item, index) => {
    const startY = ecgParams.startYList[index] + ecgParams.baseLineValue;
    const gain_ = getGainValue(ecgParams.gain, leadNameList[item]);
    const dy = (ecgParams.duvp * ecgParams.ppm * gain_) / 1000 * ecgParams.gridScale;
    list[index] = startY - dy * 0;
  })
  return list
}


// 每组useList数据在X轴移动的距离
const useListMove = (len) => {
  const dx = (ecgParams.speed * ecgParams.ppm) / ecgParams.nFs;
  const speedWidth = ecgParams.startX + dx * (len) * ecgParams.gridScale;
  return speedWidth;
}

// 计算一屏需要多少组波形数据
const getScreenLen = (width) => {
  const dx = (ecgParams.speed * ecgParams.ppm) / ecgParams.nFs;
  const lineDataLen = width / ecgParams.gridScale / dx;
  return Math.ceil(lineDataLen)
}

// 根据dx决定是否抽点
const setDx = (dx) => {
  let m_Step = 0;
  if (dx > 0) {
    m_Step = Math.round(1 / dx);
  }
  return m_Step <= 1 ? false : true
}
